package org.gpf.game.tank.online;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
/**
 * 坦克类
 * @author gaopengfei
 * @date 2015-4-13 上午11:54:37
 */
public class Tank {
	
	public static final int X_SPEED = 5; // 水平和垂直方向的速度 
	public static final int Y_SPEED = 5;

	public static final int WIDTH = 30; // 坦克的宽高
	public static final int HEIGHT = 30;
	
	int id; // 每辆坦克都有自己的id

	boolean good;						// 正方还是反方
	int x, y;							// 坦克的位置

	private boolean live = true; // 坦克是否存活

	TankClient tc; //坦克客户端

	boolean bL, bU, bR, bD; // 键盘上的4个方向

	Dir dir = Dir.STOP;//坦克的移动方向
	Dir ptDir = Dir.D;//炮管的方向

	/**
	 * 根据坦克的位置和角色【正方和反方】构建坦克
	 * @param x 坦克的横坐标
	 * @param y	坦克的纵坐标
	 * @param good 角色，正方还是反方
	 */
	public Tank(int x, int y, boolean good) {
		this.x = x;
		this.y = y;
		this.good = good;
	}

	/**
	 * 根据相关属性构建坦克
	 * @param dir 坦克的初始方向
	 * @param tc 游戏场所
	 */
	public Tank(int x, int y, boolean good, Dir dir, TankClient tc) {
		this(x, y, good);
		this.dir = dir;
		this.tc = tc;
	}

	/**
	 * 绘制坦克
	 * @param g 绘图的画笔
	 */
	public void draw(Graphics g) {
		if (!live) {
			if (!good) {
				tc.tanks.remove(this);
			}
			return;
		}

		Color c = g.getColor();
		if (good)
			g.setColor(Color.RED);	// 如果是正方，则将其颜色设置为红色，否则设置为蓝色
		else
			g.setColor(Color.BLUE);
		g.fillOval(x, y, WIDTH, HEIGHT); // 绘制椭圆表示坦克，x和y坐标为椭圆外界矩形的左上角坐标
		g.drawString("Tank id:" + id, x, y - 10);
		g.setColor(c);

		/* 坦克炮管的8个方向 */
		switch (ptDir) {
		case L:
			g.drawLine(x + WIDTH / 2, y + HEIGHT / 2, x, y + HEIGHT / 2);
			break;
		case LU:
			g.drawLine(x + WIDTH / 2, y + HEIGHT / 2, x, y);
			break;
		case U:
			g.drawLine(x + WIDTH / 2, y + HEIGHT / 2, x + WIDTH / 2, y);
			break;
		case RU:
			g.drawLine(x + WIDTH / 2, y + HEIGHT / 2, x + WIDTH, y);
			break;
		case R:
			g.drawLine(x + WIDTH / 2, y + HEIGHT / 2, x + WIDTH, y + HEIGHT / 2);
			break;
		case RD:
			g.drawLine(x + WIDTH / 2, y + HEIGHT / 2, x + WIDTH, y + HEIGHT);
			break;
		case D:
			g.drawLine(x + WIDTH / 2, y + HEIGHT / 2, x + WIDTH / 2, y + HEIGHT);
			break;
		case LD:
			g.drawLine(x + WIDTH / 2, y + HEIGHT / 2, x, y + HEIGHT);
			break;
		}

		move();
	}

	/**
	 * 控制坦克的向8个方向移动
	 */
	private void move() {
		switch (dir) {
		case L:
			x -= X_SPEED;
			break;
		case LU:
			x -= X_SPEED;
			y -= Y_SPEED;
			break;
		case U:
			y -= Y_SPEED;
			break;
		case RU:
			x += X_SPEED;
			y -= Y_SPEED;
			break;
		case R:
			x += X_SPEED;
			break;
		case RD:
			x += X_SPEED;
			y += Y_SPEED;
			break;
		case D:
			y += Y_SPEED;
			break;
		case LD:
			x -= X_SPEED;
			y += Y_SPEED;
			break;
		case STOP:
			break;
		}

		if (dir != Dir.STOP) {
			ptDir = dir;
		}

		/** 控制坦克在游戏窗体内部 */
		if (x < 0)
			x = 0;
		if (y < 30)
			y = 30;
		if (x + WIDTH > TankClient.GAME_WIDTH)
			x = TankClient.GAME_WIDTH - WIDTH;
		if (y + HEIGHT > TankClient.GAME_HEIGHT)
			y = TankClient.GAME_HEIGHT - HEIGHT;

		/*		 
		 * 		反方坦克 
		if (!good) {
			if (step == 0) {
				
				step = r.nextInt(12) + 3;
				Dir[] dirs = Dir.values();
				dir = dirs[r.nextInt(dirs.length)];
			}
			step--;
			if (r.nextInt(40) > 38)
				this.fire();
		}
		*/

	}

	/**
	 * 监听键盘事件-方向键按下开始移动
	 * @param e 键盘事件
	 */
	public void keyPressed(KeyEvent e) {
		int key = e.getKeyCode();
		switch (key) {
		case KeyEvent.VK_LEFT:
			bL = true;
			break;
		case KeyEvent.VK_UP:
			bU = true;
			break;
		case KeyEvent.VK_RIGHT:
			bR = true;
			break;
		case KeyEvent.VK_DOWN:
			bD = true;
			break;
		}
		locateDirection();
	}

	/**
	 * 确定坦克的移动方向
	 */
	private void locateDirection() {
		
		Dir olDir = this.dir;
		
		if (bL && !bU && !bR && !bD)
			dir = Dir.L;
		else if (bL && bU && !bR && !bD)
			dir = Dir.LU;
		else if (!bL && bU && !bR && !bD)
			dir = Dir.U;
		else if (!bL && bU && bR && !bD)
			dir = Dir.RU;
		else if (!bL && !bU && bR && !bD)
			dir = Dir.R;
		else if (!bL && !bU && bR && bD)
			dir = Dir.RD;
		else if (!bL && !bU && !bR && bD)
			dir = Dir.D;
		else if (bL && !bU && !bR && bD)
			dir = Dir.LD;
		else if (!bL && !bU && !bR && !bD)
			dir = Dir.STOP;
		
		/**
		 * 坦克方向改变的时候将坦克移动的消息发送到服务器
		 */
		if (dir!=olDir) {
			tc.nc.send(new TankMoveMessage(id, x,y,dir,ptDir));
		}
	}
	
	/**
	 * 键盘释放的事件处理
	 * @param e 键盘事件
	 */
	public void keyReleased(KeyEvent e) {
		int key = e.getKeyCode();
		switch (key) {
		case KeyEvent.VK_CONTROL:
			fire();
			break;
		case KeyEvent.VK_LEFT:
			bL = false;
			break;
		case KeyEvent.VK_UP:
			bU = false;
			break;
		case KeyEvent.VK_RIGHT:
			bR = false;
			break;
		case KeyEvent.VK_DOWN:
			bD = false;
			break;
		}
		locateDirection();
	}

	/**
	 * 坦克开火，发出子弹
	 * @return
	 */
	private Missile fire() {
		if (!live) {
			return null;
		}
		int x = this.x + WIDTH / 2 - Missile.WIDTH / 2;
		int y = this.y + HEIGHT / 2 - Missile.HEIGHT / 2;
		Missile m = new Missile(id,x, y, this.good, this.ptDir, this.tc);
		tc.missiles.add(m);
		
		MissileNewMessage msg = new MissileNewMessage(m);
		tc.nc.send(msg);
		
		return m;
	}

	/**
	 * @return 返回坦克的外接矩形（左上角的坐标，高度和宽度）
	 */
	public Rectangle getRect() {
		return new Rectangle(x, y, WIDTH, HEIGHT);
	}

	/**
	 * @return 坦克是否存活
	 */
	public boolean isLive() {
		return live;
	}

	/**
	 * 设置坦克的生死状态
	 * @param live 坦克的生死状态
	 */
	public void setLive(boolean live) {
		this.live = live;
	}
}
